/**
 * @file event.h
 * @author Majjcom
 * @brief An sample event system
 * @version 0.1
 * @date 2022-08-04
 * 
 * @copyright Copyright (c) 2022 Majjcom
 * 
 */

#include "arg.hpp"

#include <string>
#include <unordered_map>
#include <unordered_set>

typedef                                             void(* callbackfunc)(PARGOBJ argobj);
typedef                                             size_t callbackfunchash;
typedef                   std::unordered_set<callbackfunc> callbackfunclist;
typedef  std::unordered_map<std::string, callbackfunclist> eventHandlerMap;

/**
 * @brief Event handle class
 * 
 */
class EventHandler
{
public:
    EventHandler();
    ~EventHandler();

    /**
     * @brief 根据 eventflag 注册事件回调，可以通过 callEvent 调起所有注册为 eventflag 的函数
     * 一个 eventflag 可以有多个回调函数
     * 
     * @param eventflag 事件标志
     * @param callback  事件回调函数
     */
    void addEvnet(std::string eventflag, callbackfunc callback);

    /**
     * @brief 带参数传入的事件发生函数
     * 
     * @tparam T        传入参数类型，可以使用以下类型: int, float, double, char, bool, string, ArgPointer, unsigned int
     * @param eventflag 事件标志
     * @param args      传入参数
     */
    template<typename T>
    void callEvent(std::string eventflag, Argobj<T> args);

    /**
     * @brief 简单的事件发生器
     * 
     * @param eventflag 事件标志
     */
    void callEvent(std::string eventflag);

    /**
     * @brief 通过流操作符发生事件
     * 
     * @param str_ 事件标志
     * @return EventHandler& 
     */
    EventHandler& operator<<(const std::string& eventflag);

    /**
     * @brief 注销事件
     * 
     * @param eventflag 事件标志
     * @param callback  事件回调函数
     */
    void unRegistEvent(std::string eventflag, callbackfunc callback);
private:
    eventHandlerMap handles;

    template<typename T>
    void caller(std::string eventflag, Argobj<T>& args);
};
